Categories
React

Framer Motion — Animation Sequence and Layout Animations

Spread the love

With the Framer Motion library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with Framer Motion.

Sequencing

The controls.start method returns a promise so we can use it to sequence animations.

For example, we can write:

import React, { useEffect } from "react";
import { motion, useAnimation } from "framer-motion";

export default function App() {
  const controls = useAnimation();

  const sequence = async () => {
    await controls.start({ x: 0 });
    return await controls.start({ opacity: 1 });
  };

  useEffect(() => {
    sequence();
  }, []);

  return (
    <motion.div
      animate={controls}
      style={{ backgroundColor: "red", width: 100, height: 100 }}
    />
  );
}

We have the sequence function that calls controls.start with different styles.

So this is what we’ll see when we load our component.

Dynamic Start

We can call controls.start dynamically.

For example, we can write:

import React, { useEffect } from "react";
import { motion, useAnimation } from "framer-motion";

export default function App() {
  const controls = useAnimation();

  useEffect(() => {
    controls.start((i) => ({
      opacity: 0,
      x: 100,
      transition: { delay: i * 0.3 }
    }));
  }, []);

  return (
    <ul>
      <motion.li custom={0} animate={controls}>
        foo
      </motion.li>
      <motion.li custom={1} animate={controls}>
        bar
      </motion.li>
      <motion.li custom={2} animate={controls}>
        baz
      </motion.li>
    </ul>
  );
}

We pass in a callback with the i parameter, which is the value that we passed into the custom prop.

And we pass into the animate prop to set the controls to control the animation.

Layout Animations

We can animate layouts with Framer Motion

For example, we can write:

App.js

import React, { useState } from "react";
import { motion } from "framer-motion";
import "./styles.css";

const spring = {
  type: "spring",
  stiffness: 700,
  damping: 30
};

export default function App() {
  const [isOn, setIsOn] = useState(false);

  const toggleSwitch = () => setIsOn(!isOn);

  return (
    <div className="switch" data-isOn={isOn} onClick={toggleSwitch}>
      <motion.div className="handle" layout transition={spring} />
    </div>
  );
}

styles.css

html,
body {
  min-height: 100vh;
  padding: 0;
  margin: 0;
}

* {
  box-sizing: border-box;
}

.App {
  font-family: sans-serif;
  text-align: center;
}

.switch {
  width: 160px;
  height: 100px;
  background-color: green;
  display: flex;
  justify-content: flex-start;
  border-radius: 50px;
  padding: 10px;
  cursor: pointer;
}

.switch[data-isOn="true"] {
  justify-content: flex-end;
}

.handle {
  width: 80px;
  height: 80px;
  background-color: white;
  border-radius: 40px;
}

We add the spring animation effect and pass that into the transition prop.

The onClick prop has the function to control the isOn state.

The layout prop lets us animate the layout of the div.

We add the styles to style our div into a switch.

justify-content set to flex-start has the switch bottom on the left. and flex-end puts the switch button to the right.

Conclusion

We can control our animation progress with Framer Motion.

And we can apply animations for layouts.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *